perm filename C3[CLS,LSP] blob
sn#871197 filedate 1989-03-17 generic text, type C, neo UTF8
COMMENT ā VALID 00002 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 %Start Part 3 of 6 concep.tex
C00038 ENDMK
Cā;
%Start Part 3 of 6 concep.tex
The following might appear to be a conflicting set of definitions:
\screen!
(defclass pie (apple cinnamon) ())
(defclass pastry (cinnamon apple) ())
(defclass apple () ())
(defclass cinnamon () ())
\endscreen!
The class precedence list for {\tt pie} is {\tt (pie apple cinnamon
standard-object t)}.
The class precedence list for {\tt pastry} is {\tt (pastry cinnamon apple
standard-object t)}.
It is not a problem for {\tt apple} to precede {\tt cinnamon} in the
ordering of the superclasses of {\tt pie} but not in the ordering for
{\tt pastry}. However, it is not possible to build a new class that
has both {\tt pie} and {\tt pastry} as superclasses.
\endsubSection%{Examples}
\endSection%{Determining the Class Precedence List}
\beginSection{Generic Functions and Methods}
A {\bit generic function\/} is a function whose behavior depends on
the classes or identities of the arguments supplied to it. The {\bit
methods} define the class-specific behavior and operations of the
generic function. The following sections describe generic functions
and methods.
\beginsubSection{Introduction to Generic Functions}
A generic function object contains a set of methods, a
lambda-list, a method combination type, and other information.
Like an ordinary Lisp function, a generic function takes arguments,
performs a series of operations, and perhaps returns useful values.
An ordinary function has a single body of code that is always executed
when the function is called. A generic function has a set of bodies
of code of which a subset is selected for execution. The selected
bodies of code and the manner of their combination are determined by
the classes or identities of one or more of the arguments to the
generic function and by its method combination type.
Ordinary functions and generic functions are called with identical
syntax.
Generic functions are true functions that can be passed as arguments and
used as the first argument to {\bf funcall} and {\bf apply}.
In Common Lisp, a name can be given to an ordinary function in one of
two ways: a {\bit global\/} name can be given to a function using the
{\bf defun} construct; a {\bit local\/} name can be given using the
{\bf flet} or {\bf labels} special forms. A generic function can be
given a global name using the {\bf defmethod} or {\bf defgeneric}
construct. A generic function can be given a local name using the
{\bf generic-flet}, {\bf generic-labels}, or {\bf with-added-methods}
special forms. The name of a generic function, like the name of an
ordinary function, can be either a symbol or a two-element list whose
first element is {\bf setf} and whose second element is a symbol.
This is true for both local and global names.
The {\bf generic-flet} special form creates new local generic
functions using the set of methods specified by the method definitions
in the {\bf generic-flet} form. The scoping of generic function names
within a {\bf generic-flet} form is the same as for {\bf flet}.
The {\bf generic-labels} special form creates a set of new mutually
recursive local generic functions using the set of methods specified
by the method definitions in the {\bf generic-labels} form. The
scoping of generic function names within a {\bf generic-labels} form
is the same as for {\bf labels}.
The {\bf with-added-methods} special form creates new local generic
functions by adding the set of methods specified by the method
definitions with a given name in the {\bf with-added-methods} form to
copies of the methods of the lexically visible generic function of the
same name. If there is a lexically visible ordinary function of the
same name as one of specified generic functions, that function
becomes the method function of the default method for the new generic
function of that name.
The {\bf generic-function} macro creates an anonymous generic
function with the set of methods specified by the method definitions
in the {\bf generic-function} form.
When a {\bf defgeneric} form is evaluated, one of three actions
is taken:
\beginlist
\item{\bull} If a generic function of the given name already exists,
the existing generic function object is modified. Methods specified
by the current {\bf defgeneric} form are added, and any methods in the
existing generic function that were defined by a previous {\bf
defgeneric} form are removed. Methods added by the current {\bf
defgeneric} form might replace methods defined by {\bf defmethod} or
{\bf defclass}. No other methods in the generic function are affected
or replaced.
\item{\bull} If the given name names a non-generic function, a
macro, or a special form, an error is signaled.
\item{\bull} Otherwise a generic function is created with the
methods specified by the method definitions in the {\bf defgeneric}
form.
\endlist
Some forms specify the options of a generic function,
such as the type of method combination it uses or its argument
precedence order. These forms will be referred to as ``forms that
specify generic function options.'' These forms are: {\bf defgeneric},
{\bf generic-function}, {\bf generic-flet}, {\bf generic-labels}, and
{\bf with-added-methods}.
Some forms define methods for a generic function. These forms will be
referred to as ``method-defining forms.'' These forms are: {\bf
defgeneric}, {\bf defmethod}, {\bf generic-function}, {\bf
generic-flet}, {\bf generic-labels}, {\bf with-added-methods}, and
{\bf defclass}. Note that all the method-defining forms except {\bf
defclass} and {\bf defmethod} can specify generic function options and
so are also forms that specify generic function options.
\endsubSection%{Introduction to Generic Functions}
\beginsubSection{Introduction to Methods}
A method object contains a method function, a sequence of {\bit
parameter specializers\/} that specify when the given method is
applicable, a lambda-list, and a sequence of {\bit qualifiers\/} that
are used by the method combination facility to distinguish among
methods.
A method object is not a function and cannot be invoked as a function.
Various mechanisms in the \OS\ take a method object and invoke its method
function, as is the case when a generic function is invoked. When this
occurs it is said that the method is invoked or called.
A method-defining form contains the code that is to be run when the
arguments to the generic function cause the method that it defines to
be invoked. When a method-defining form is evaluated, a method object
is created and one of four actions is taken:
\beginlist
\item{\bull} If a generic function of the given name already exists
and if a method object already exists that agrees with the new one on
parameter specializers and qualifiers, the new method object replaces
the old one. For a definition of one method agreeing with another on
parameter specializers and qualifiers, see the section
``Agreement on Parameter Specializers and Qualifiers.''
\item{\bull} If a generic function of the given name already exists
and if there is no method object that agrees with the new one on
parameter specializers and qualifiers, the existing generic function
object is modified to contain the new method object.
\item{\bull} If the given name names a non-generic function, a macro,
or a special form, an error is signaled.
\item{\bull} Otherwise a generic function is created with the methods
specified by the method-defining form.
\endlist
If the lambda-list of a new method is not congruent with the lambda-list
of the generic function, an error is signaled. If a
method-defining form that cannot specify generic function options
creates a new generic function, a lambda-list for that generic
function is derived from the lambda-lists of the methods in the
method-defining form in such a way as to be congruent with them. For
a discussion of {\bit congruence}, see the section ``Congruent
Lambda-lists for All Methods of a Generic Function.''
Each method has a {\bit specialized lambda-list}, which determines
when that method can be applied. A specialized lambda-list is like
an ordinary lambda-list except that a {\bit specialized parameter\/}
may occur instead of the name of a required parameter. A specialized parameter
is a list {\tt ({\it variable-name parameter-specializer-name\/})},
where {\it parameter-specializer-name\/} is one of the following:
\beginlist
\item{\bull} A name that names a class
\item{\bull} {\tt ({\bf eql} {\it form\/})}
\endlist
A parameter specializer name denotes a parameter specializer as follows:
\beginlist
\item{\bull} A name that names a class denotes that class.
\item{\bull} The list {\tt ({\bf eql} {\it form\/})} denotes {\tt
({\bf eql} {\it object\/})}, where {\it object\/} is the result of
evaluating {\it form\/}. The form {\it form\/} is evaluated in the
lexical environment in which the method-defining form is
evaluated. Note that {\it form\/} is evaluated only once, at the time
the method is defined, not each time the generic function is called.
\endlist
Parameter specializer names are used in macros intended as the
user-level interface ({\bf defmethod}), while parameter specializers
are used in the functional interface.
Only required parameters may be specialized, and there must be a
parameter specializer for each required parameter. For notational
simplicity, if some required parameter in a specialized lambda-list in
a method-defining form is simply a variable name, its parameter
specializer defaults to the class named {\bf t}.
Given a generic function and a set of arguments, an {\bit applicable
method\/} is a method for that generic function whose parameter
specializers are satisfied by their corresponding arguments. The
following definition specifies what it means for a method to be
applicable and for an argument to satisfy a parameter specializer.
Let $\langle A\sub 1, \ldots, A\sub n\rangle$ be the required
arguments to a generic function in order. Let $\langle P\sub 1,
\ldots, P\sub n\rangle$ be the parameter specializers corresponding to
the required parameters of the method $M$ in order. The method $M$ is
{\bit applicable\/} when each $A\sub i$ {\bit satisfies\/} $P\sub i$.
If $P\sub i$ is a class, and if $A\sub i$ is an instance of a class
$C$\negthinspace, then it is said that $A\sub i$ {\bit satisfies\/}
$P\sub i$ when $C=P\sub i$ or when $C$ is a subclass of $P\sub i$. If
$P\sub i$ is {\tt ({\bf eql} {\it object\/})}, then it is said that
$A\sub i$ satisfies $P\sub i$ when the function {\bf eql} applied to
$A\sub i$ and {\it object} is true.
Because a parameter specializer is a type specifier, the function {\bf
typep} can be used during method selection to determine whether an
argument satisfies a parameter specializer. In general a
parameter specializer cannot be a type specifier list, such as {\tt
({\bf vector single-float})}. The only parameter specializer that can
be a list is {\tt ({\bf eql} {\it object\/})}. This requires that
Common Lisp be modified to include the type specifier {\bf eql} to be
defined as if the following were evaluated:
$$\hbox{{\tt ({\bf deftype eql} ({\it object\/})
`({\bf member} {\it ,object\/}))}}$$
A method all of whose parameter specializers are the class named {\bf
t} is called a {\bit default method}; it is always applicable but
may be shadowed by a more specific method.
Methods can have {\bit qualifiers}, which give the method combination
procedure a way to distinguish among methods. A method that has one
or more qualifiers is called a {\bit qualified\/} method.
A method with no qualifiers is called an {\bit unqualified method}.
A qualifier is any object other than a list, that is,
any non-{\bf nil} atom. The qualifiers defined by standard method combination
and by the built-in method combination types are symbols.
In this specification, the terms {\bit primary method\/} and {\bit
auxiliary method\/} are used to partition methods within a method
combination type according to their intended use. In standard method
combination, primary methods are unqualified methods and auxiliary
methods are methods with a single qualifier that is one of {\bf
:around}, {\bf :before}, or {\bf :after}. When a method combination
type is defined using the short form of {\bf
define-method-combination}, primary methods are methods qualified with
the name of the type of method combination, and auxiliary methods have
the qualifier {\bf :around}. Thus the terms {\bit primary method\/}
and {\bit auxiliary method\/} have only a relative definition within a
given method combination type.
\endsubSection%{Introduction to Methods}
\beginsubSection{Agreement on Parameter Specializers and Qualifiers}
Two methods are said to agree with each other on parameter specializers
and qualifiers if the following conditions hold:
\beginlist
\item{1.} Both methods have the same number of required parameters.
Suppose the parameter specializers of the two methods are
$P\sub{1,1}\ldots P\sub{1,n}$ and $P\sub{2,1}\ldots P\sub{2,n}$.
\item{2.} For each $1\leq i\leq n$, $P\sub{1,i}$ agrees with $P\sub{2,i}$.
The parameter specializer $P\sub{1,i}$ agrees with $P\sub{2,i}$ if
$P\sub{1,i}$ and $P\sub{2,i}$ are the same class or if
$P\sub{1,i}=\hbox{{\tt({\bf eql} $\hbox{{\it object}}\sub 1$)}}$,
$P\sub{2,i}=\hbox{{\tt({\bf eql} $\hbox{{\it object}}\sub 2$)}}$, and
{\tt ({\bf eql} $\hbox{{\it object}}\sub 1$ $\hbox{{\it object}}\sub 2$)}.
Otherwise $P\sub{1,i}$ and $P\sub{2,i}$ do not agree.
\newpage
\item{3.} The lists of qualifiers of both methods contain the same
non-{\bf nil} atoms in the same order. That is, the lists are {\bf equal}.
\endlist
\endsubSection%{Agreement on Parameter Specializers and Qualifiers}
\beginsubSection{Congruent Lambda-Lists for All Methods of a Generic Function}
These rules define the congruence of a set of lambda-lists, including the
lambda-list of each method for a given generic function and the
lambda-list specified for the generic function itself, if given.
\beginlist
\item{1.} Each lambda-list must have the same number of required
parameters.
\item{2.} Each lambda-list must have the same number of optional
parameters. Each method can supply its own default for an optional
parameter.
\item{3.} If any lambda-list mentions {\bf \&rest} or {\bf \&key}, each
lambda-list must mention one or both of them.
\item{4.} If the generic function lambda-list mentions {\bf \&key}, each
method must accept all of the keyword names mentioned after {\bf \&key},
either by accepting them explicitly, by specifying {\bf
\&allow-other-keys}, or by specifying {\bf \&rest} but not {\bf \&key}.
Each method can accept additional keyword arguments of its own. The
checking of the validity of keyword names is done in the generic
function, not in each method. A method is invoked as if the keyword
argument pair whose keyword is {\bf :allow-other-keys} and whose value
is {\bf t} were supplied, though no such argument pair will be passed.
\item{5.} The use of {\bf \&allow-other-keys} need not be consistent
across lambda-lists. If {\bf \&allow-other-keys} is mentioned in
the lambda-list of any applicable method or of the generic function,
any keyword arguments may be mentioned in the call to the
generic function.
\item{6.} The use of {\bf \&aux} need not be consistent across methods.
If a method-defining form that cannot specify generic function options
creates a generic function, and if the lambda-list for the method
mentions keyword arguments, the lambda-list of the generic function
will mention {\bf \&key} (but no keyword arguments).
\endlist
\endsubSection%{Congruent Lambda-lists for All Methods of a Generic Function}
%\newpage
\beginsubSection{Keyword Arguments in Generic Functions and Methods}
When a generic function or any of its methods mentions {\bf \&key} in
a lambda-list, the specific set of keyword arguments accepted by the
generic function varies according to the applicable methods. The set
of keyword arguments accepted by the generic function for a particular
call is the union of the keyword arguments accepted by all applicable
methods and the keyword arguments mentioned after {\bf \&key} in the
generic function definition, if any. A method that has {\bf \&rest}
but not {\bf \&key} does not affect the set of acceptable keyword
arguments. If the lambda-list of any applicable method or of the
generic function definition contains {\bf \&allow-other-keys}, all
keyword arguments are accepted by the generic function.
The lambda-list congruence rules require that each method
accept all of the keyword arguments mentioned after {\bf \&key} in the
generic function definition, by accepting them explicitly, by
specifying {\bf \&allow-other-keys}, or by specifying {\bf \&rest} but
not {\bf \&key}. Each method can accept additional keyword arguments
of its own, in addition to the keyword arguments mentioned in the
generic function definition.
If a generic function is passed a keyword argument that no applicable
method accepts, an error is signaled.
For example, suppose there are two methods defined for {\tt width}
as follows:
\screen!
(defmethod width ((c character-class) &key font) ...)
(defmethod width ((p picture-class) &key pixel-size) ...)
\endscreen!
\noindent Assume that there are no other methods and no generic
function definition for {\tt width}. The evaluation of the
following form will signal an error because the keyword argument
{\tt :pixel-size} is not accepted by the applicable method.
\screen!
(width (make-instance `character-class :char \#\\Q)
:font 'baskerville :pixel-size 10)
\endscreen!
The evaluation of the following form will signal an error.
\screen!
(width (make-instance `picture-class :glyph (glyph \#\\Q))
:font 'baskerville :pixel-size 10)
\endscreen!
The evaluation of the following form will not signal an error
if the class named {\tt character-picture-class} is a subclass of
both {\tt picture-class} and {\tt character-class}.
\screen!
(width (make-instance `character-picture-class :char \#\\Q)
:font 'baskerville :pixel-size 10)
\endscreen!
\endsubSection%{Keyword Arguments in Generic Functions and Methods}
\endSection%{Generic Functions and Methods}
\beginSection{Method Selection and Combination}
When a generic function is called with particular arguments, it must
determine the code to execute. This code is called the {\bit effective
method\/} for those arguments. The effective method is a {\bit
combination\/} of the applicable methods in the generic function. A
combination of methods is a Lisp expression that contains calls to some or
all of the methods. If a generic function is
called and no methods apply, the generic function {\bf
no-applicable-method} is invoked.
When the effective method has been determined, it is invoked with the same
arguments that were passed to the generic function. Whatever values it
returns are returned as the values of the generic function.
\beginsubSection{Determining the Effective Method}
The effective method is determined by the following three-step procedure:
\beginlist
\item{1.}{Select the applicable methods.}
\item{2.}{Sort the applicable methods by precedence order, putting
the most specific method first.}
\item{3.}{Apply method combination to the sorted list of
applicable methods, producing the effective method.}
\endlist
\beginsubsubsection{Selecting the Applicable Methods}
This step is described in the section ``Introduction to Methods.''
\endsubsubsection%{Selecting the Applicable Methods}
\beginsubsubsection{Sorting the Applicable Methods by Precedence Order}
To compare the precedence of two methods, their parameter specializers
are examined in order. The default examination order is from left to
right, but an alternative order may be specified by the {\bf
:argument-precedence-order} option to {\bf defgeneric} or to any of
the other forms that specify generic function options.
The corresponding parameter specializers from each method are
compared. When a pair of parameter specializers are equal, the next
pair are compared for equality. If all corresponding parameter
specializers are equal, the two methods must have different
qualifiers; in this case, either method can be selected to precede the
other.
If some corresponding parameter specializers are not equal, the first
pair of parameter specializers that are not equal determines the
precedence. If both parameter specializers are classes, the more
specific of the two methods is the method whose parameter specializer
appears earlier in the class precedence list of the corresponding
argument. Because of the way in which the set of applicable methods
is chosen, the parameter specializers are guaranteed to be present in
the class precedence list of the class of the argument.
If just one parameter specializer is {\tt ({\bf eql} {\it
object\/})}, the method with that parameter specializer precedes the
other method. If both parameter specializers are {\bf eql}
forms, the
specializers must be the same (otherwise the two methods would
not both have been applicable to this argument).
The resulting list of applicable methods has the most specific
method first and the least specific method last.
\endsubsubsection%{Sorting the Applicable Methods by Precedence Order}
\beginsubsubsection{Applying Method Combination to the Sorted List of Applicable Methods}
In the simple case---if standard method combination is used and all
applicable methods are primary methods---the effective method is the
most specific method. That method can call the next most specific
method by using the function {\bf call-next-method}. The method that
{\bf call-next-method} will call is referred to as the {\bit next
method}. The predicate {\bf next-method-p} tests whether a next
method exists. If {\bf call-next-method} is called and there is no
next most specific method, the generic function {\bf no-next-method}
is invoked.
%End Part 3 of 6 concep.tex